package com.linkstec.base.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.linkstec.base.constant.SysConstant;
import com.linkstec.base.entity.User;
import com.linkstec.base.mapper.UserInfoMapper;
import com.linkstec.base.menus.TicketTypeEnum;
import com.linkstec.base.service.WechatExternalContactService;
import com.linkstec.base.service.WechatTokenManageService;
import com.linkstec.base.util.*;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class WechatExternalContactServiceImpl implements WechatExternalContactService {

	Logger logger = LoggerFactory.getLogger(WechatExternalContactServiceImpl.class);

	@Autowired
	RedisUtil redisUtil;
	@Autowired
	PropUtil propUtil;
	@Autowired
	WechatTokenManageService tokenManageService;
	@Autowired
	UserInfoMapper userInfoMapper;

	public DataResultUtil sendGetUser(JSONObject jsonObject, String url) {
		return sendGet(tokenManageService.getUserToken(), jsonObject, url);
	}

	public DataResultUtil sendGetUserByAccount(JSONObject jsonObject, String url) {
		User user = new User();
		String accountId = jsonObject.get("accountId").toString();
			if(StringUtils.isNotBlank(accountId)){
			user = userInfoMapper.selectUserByAccountId(accountId);
			if(StringUtils.isNotBlank(user.getUserId())){
				jsonObject.put("userid",user.getUserId());
			}else{
				return DataResultUtil.getFailureResult("当前账号没有关联企业微信",accountId);
			}
		}else{
				return DataResultUtil.getFailureResult("账号为空",accountId);
			}
		return sendGet(tokenManageService.getUserToken(), jsonObject, url);
	}

	public DataResultUtil sendGetCustomer(JSONObject jsonObject, String url) {
		return sendGet(tokenManageService.getCustomerToken(), jsonObject, url);
	}

	private DataResultUtil sendGet(String token, JSONObject jsonObject, String url) {
		jsonObject.put("access_token", token);
		String urlNew = handleURL(url);
		if (urlNew == null) {
			return DataResultUtil.getFailureResult("url为空", null);
		}
		String jsonobject = HttpClientUtil.sendGet(urlNew, jsonObject);
		if (!StringUtils.isEmpty(jsonobject)) {
			return DataResultUtil.getSuccessResult(JSONObject.parseObject(jsonobject));
		}
		return DataResultUtil.getFailureResult("请求结果为空", null);
	}

	public DataResultUtil sendPostUser(JSONObject jsonObject, String url) {
		return sendPost(tokenManageService.getUserToken(), jsonObject, url);
	}

	public DataResultUtil sendPostCustomer(JSONObject jsonObject, String url) {
		return sendPost(tokenManageService.getCustomerToken(), jsonObject, url);
	}

	private DataResultUtil sendPost(String token, JSONObject jsonObject, String url) {
		jsonObject.put("access_token", token);
		String urlNew = handleURL(url);
		if (urlNew == null) {
			return DataResultUtil.getFailureResult("url为空", null);
		}
		String jsonobject = HttpClientUtil.sendPost(urlNew, jsonObject);
		if (!StringUtils.isEmpty(jsonobject)) {
			return DataResultUtil.getSuccessResult(JSONObject.parseObject(jsonobject));
		}
		return DataResultUtil.getFailureResult("请求结果为空", null);
	}

	/**
	 * 替换url里的 . 为 /
	 * @param url
	 * @return
	 */
	private String handleURL(String url) {
		if (!StringUtils.isBlank(url)) {
			return propUtil.prop_qywechat_qyapi_url + url.replaceAll(SysConstant.spot, SysConstant.slash);
		}
		logger.error("url为空！");
		return null;
	}

	public DataResultUtil getAgentConfigParameter(String url, TicketTypeEnum ticketTypeEnum) {
		// 获取签名相关
		JSONObject signatureJSON = getSignatureJSON(url,ticketTypeEnum);
		// 封装结果
		JSONObject data = new JSONObject();
		data.put("corpid", propUtil.prop_qywechat_corpid);
		data.put("agentid", propUtil.prop_qywechat_agentid);
		data.put("timestamp", signatureJSON.getString("timestamp"));
		data.put("nonceStr", signatureJSON.getString("nonceStr"));
		data.put("signature", signatureJSON.getString("signature"));
		return DataResultUtil.getSuccessResult(data);
	}

	// 从redis中获取签名相关
	private JSONObject getSignatureJSON(String url,TicketTypeEnum ticketTypeEnum) {
		JSONObject signatureJSON = new JSONObject();
		// 1.获取签名时间戳
		String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
		signatureJSON.put("timestamp", timestamp);
		// 2.随机字符串
		String nonceStr = RandomStringUtils.randomAlphanumeric(16);
		signatureJSON.put("nonceStr", nonceStr);
		// 3.获取签名
		String signature = getSignatureRedis(nonceStr, timestamp, url, ticketTypeEnum);
		signatureJSON.put("signature", signature);
		return signatureJSON;
	}

	// 签名加密
	private String getSignatureRedis( String nonceStr, String timestamp, String url, TicketTypeEnum ticketTypeEnum) {
		String ticket = getTicket(ticketTypeEnum);
		if (!StringUtils.isEmpty(ticket)) {
			// 对ticket加密得到签名
			logger.info("加密签名：ticket = {}，nonceStr = {}，timestamp = {}，url = {}", ticket, nonceStr, timestamp, url);
			String unEncryptStr = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + url;
			String signature = SHA1Util.getSha1(unEncryptStr);
			logger.info("加密签名结果：signature = {}", signature);
			return signature;
		} else {
			logger.error("ticket获取失败");
			return null;
		}
	}

	// ticket获取
	private String getTicket(TicketTypeEnum ticketTypeEnum) {
		String ticket = null;
		if (ticketTypeEnum == TicketTypeEnum.AGENT_CONFIG) {
			ticket = (String) redisUtil.get(SysConstant.AGENT_CONFIG);
		} else {
			ticket = (String) redisUtil.get(SysConstant.CONFIG);
		}
		if (StringUtils.isEmpty(ticket)) {
			String token = tokenManageService.getUserToken();
			String result = null;
			// 获取未加密签名
			JSONObject ticketJSON = new JSONObject();
			ticketJSON.put("access_token", token);
			// 判断获取ticket的类型
			if (ticketTypeEnum == TicketTypeEnum.AGENT_CONFIG) {
				ticketJSON.put("type", "agent_config");
				result = HttpClientUtil.sendGet(propUtil.prop_qywechat_qyapi_url + propUtil.prop_qywechat_get_jsapi_agent_ticket_url, ticketJSON);
				ticket = JSONObject.parseObject(result).getString("ticket");
				redisUtil.set(SysConstant.AGENT_CONFIG, ticket, SysConstant.base_redis_time);
			} else {
				result = HttpClientUtil.sendGet(propUtil.prop_qywechat_qyapi_url + propUtil.prop_qywechat_get_jsapi_ticket_url, ticketJSON);
				ticket = JSONObject.parseObject(result).getString("ticket");
				redisUtil.set(SysConstant.CONFIG, ticket, SysConstant.base_redis_time);
			}
		}
		return ticket;
	}

}
